package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
	"strconv"
	"strings"
)

type Node struct {
	row int
	col int
	val int
}

//用切片储存稀疏数组
var (
	sparsearray = make([]Node, 0)
)

func (n Node) String() string {
	return strconv.Itoa(n.row) + "," + strconv.Itoa(n.col) + "," + strconv.Itoa(n.val)
}

/*
	稀疏数组，先将稀疏数组储存到文件中，然后再从文件中回复该数组
*/

/*
	将数据写入文本文件，传入要写入的切片和文件名
*/
func writeToFile(data []Node, fileName string) (err error) {
	file, err := os.OpenFile(fileName, os.O_WRONLY|os.O_CREATE, 0777)
	if err != nil {
		fmt.Println("文件打开出错,err=", err)
		return
	}

	defer file.Close()

	writer := bufio.NewWriter(file)
	for i := 0; i < len(data); i++ {
		content := data[i].String()
		_, err = writer.WriteString(content + "\n")
	}
	//带有缓存区，最后刷新，强制写入
	err = writer.Flush()
	return
}

/*
	从文件中读取稀疏数组，并将其转化为Node类型的切片返回
*/
func readFromFile(fileName string) (data []Node, err error) {
	file, err := os.Open(fileName)
	if err != nil {
		fmt.Println("文件打开出错,err=", err)
		return
	}

	defer file.Close()
	data = make([]Node, 0)

	reader := bufio.NewReader(file)
	for {
		content, err := reader.ReadString('\n') //按行读取文件

		//证明读取到文件末尾
		if err == io.EOF {
			break
		}
		//fmt.Println("content=", content)
		arr := strings.Split(content, ",")
		nodeRow, err := strconv.Atoi(arr[0])
		nodeCol, err := strconv.Atoi(arr[1])
		nodeVal, err := strconv.Atoi(arr[2])

		n := Node{
			row: nodeRow,
			col: nodeCol,
			val: nodeVal,
		}
		data = append(data, n)
	}
	return
}

func main() {

	var arr [11][11]int
	arr[1][2] = 1
	arr[2][3] = 2
	title := Node{ //将头元素加入节点，储存该稀疏数组的行数和列数
		row: 11,
		col: 11,
		val: 0,
	}

	sparsearray = append(sparsearray, title)

	//将arr转成稀疏数组
	for i, v1 := range arr {
		for j, v2 := range v1 {
			if arr[i][j] != 0 {
				n := Node{
					row: i,
					col: j,
					val: v2,
				}
				sparsearray = append(sparsearray, n)
			}
		}
	}
	fmt.Println(sparsearray)

	filePath := "D:\\golang_workstation\\src\\vs_code\\struct-algorithm\\main\\01sparsearray\\sparsearr.data"

	//将该稀疏数组写入文件储存
	err := writeToFile(sparsearray, filePath)
	if err == nil {
		fmt.Println("稀疏数组写入文件成功...")
	}

	data, err := readFromFile(filePath)
	fmt.Println("data=", data)
	//arrShape := data[0]
	//go的数组在建立时必须确定好长度，所以必须将数组长度写死
	//var readArr [arrShape.row][arrShape.col]int
	var readArr [11][11]int
	for i := 1; i < len(data); i++ {
		readArr[data[i].row][data[i].col] = data[i].val
	}

	for _, v1 := range arr {
		for _, v2 := range v1 {
			fmt.Print(v2)
			fmt.Print("\t")
		}
		fmt.Print("\n")
	}

}
